// vue3 关闭element-plus 消息提示的方法  vue2内用element-ui替换掉就行
// 使用方法：
// connectWebsocket(
//   'socket地址',
//   (data) => {
//      返回数据
//      console.log(data)
//   }
// )
import { message, closeAllMessage } from "@/utils/message";

// websocket实例
let websock = null;
// ws连接地址
let wsUrl = null;
// let userId = null;
// 是否执行重连 true/不执行 ； false/执行
let lockReconnect = false;
// 重连定时器
let wsCreateHandler = null;
// 重连次数
let reconnectCount = 0;
// 连接成功，执行回调函数
let messageCallback = null;
// 连接失败，执行回调函数
let errorCallback = null;
// 发送给后台的数据
let sendDatas = {};

let redata: any = {}
var timeoutObj = null;

export {
  websock
}

/**
 * 发起websocket请求函数
 * @param {string} url ws连接地址
 * @param {function} successCallback 接收到ws数据，对数据进行处理的回调函数
 */
export const connectWebsocket = (url, successCallback) => {
  wsUrl = url;
  createWebSoket();
  messageCallback = successCallback;
}

// 手动关闭websocket （这里手动关闭会执行onclose事件）
export const closeWebsocket = () => {
  if (websock) {
    message(`手动关闭websocket`, { type: "success" });
    websock.close() // 关闭websocket
    // websock.onclose() // 关闭websocket(如果上面的关闭不生效就加上这一条)
    // 关闭重连
    lockReconnect = true;
    wsCreateHandler && clearTimeout(wsCreateHandler);
  }
}

// 创建ws函数
const createWebSoket = () => {
  if (typeof (WebSocket) === 'undefined') {
    message(`您的浏览器不支持WebSocket,无法获取数据`, { type: "warning" });
    return false
  }

  try {
    websock = new WebSocket(wsUrl);
    initWsEventHandle();
  } catch (e) {
    message(`连接异常，开始重连`, { type: "warning" });
    reconnect();
  }
}

// 初始化 WebSocket
const initWsEventHandle = () => {
  try {
    // 连接成功
    websock.onopen = (event) => {
      onWsOpen(event);
    }

    // 监听服务器端返回的信息
    websock.onmessage = (event) => {
      onWsMessage(event);
    }

    websock.onclose = (event) => {
    //   message(`onclose执行关闭事件`, { type: "success" });
      onWsClose(event);
    }

    websock.onerror = (event) => {
    //   message(`onerror执行error事件,开始重连`, { type: "warning" });
    //   console.log("异常")
      onWsError(event);
      reconnect();
    }
  } catch (err) {
    // message(`绑定事件没有成功，开始重连`, { type: "success" });
    reconnect();
  }
}

const onWsOpen = (event) => {
  // // 客户端与服务器端通信
  // websock.send('我发送消息给服务端');
  // 添加状态判断，当为OPEN时，发送消息
  if (websock.readyState === websock.OPEN) { // websock.OPEN = 1 
    // 发给后端的数据需要字符串化
    // websock.send(JSON.stringify(sendDatas));
  }
  if (websock.readyState === websock.CLOSED) { // websock.CLOSED = 3 
    message(`ws连接异常,开始重连`, { type: "warning" });
    reconnect();
    // errorCallback(event);
  }
}
const onWsMessage = (event) => {
  const data = JSON.parse(event.data);
  // if (data.Type === 'Log') {
  //   redata.LogData = data.LogData
  // } else {
  //   redata.AgvData = data.AgvData
  //   if (data.Type === 'AgvJob') {
  //     redata.JobData = data.JobData
  //     redata.CrossData = data.CrossData
  //   }
  // }

  messageCallback(data);
}
const onWsClose = (event) => {
  // e.code === 1000  表示正常关闭。 无论为何目的而创建, 该链接都已成功完成任务。
  // e.code !== 1000  表示非正常关闭。
//   console.log('onclose event: ', event)
  if (event && event.code !== 1000) {
    // message(`非正常关闭`, { type: "warning" });
    // errorCallback(event);
    // 如果不是手动关闭，这里的重连会执行；如果调用了手动关闭函数，这里重连不会执行
    reconnect();
  }
}
const onWsError = (event) => {
//   console.log('连接失败')
}

// 重连函数
const reconnect = () => {
  if (lockReconnect) {
    return;
  }
  message(`连接错误，3秒后重连`, { type: "warning" });
  lockReconnect = true;
  // 没连接上会一直重连，设置延迟避免请求过多
  wsCreateHandler && clearTimeout(wsCreateHandler);
  reconnectCount++

  wsCreateHandler = setTimeout(() => {
    if (reconnectCount === 10) {
      closeAllMessage()
      message('重连次数过多，请先检查网络或socket服务', { type: "warning" });
      return false;
    }
    message('重连...' + wsUrl, { type: "warning" });
    createWebSoket();
    lockReconnect = false;
  }, 3000);
}